package com.paradogs.gs.utils;

import com.paradogs.framework.utils.ContextUtils;
import com.paradogs.framework.utils.MsgUtils;
import com.paradogs.gs.misc._NetMgr;
import com.paradogs.gs.modules.Player;
import com.paradogs.gs.misc.PlayerSession;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;

/**
 * @author: yumi
 * @date: 2023/12/29  23:57
 * @Description: TODO
 */
@Slf4j
public class PlayerUtils {

    private static Map<Channel, PlayerSession> channelMap = new ConcurrentHashMap<>();
    private static Map<Long, PlayerSession> uidMap = new ConcurrentHashMap<>();

    /** 获得当前请求的玩家数据 */
    public static Player cur() {
        // 后面加个前置过滤器判断是否登录
        return getSession(ContextUtils.getChannel()).getPlayer();
    }

    public static PlayerSession getSession(Long uid) {
        // 后面加个前置过滤器判断是否登录
        return uidMap.get(uid);
    }

    public static PlayerSession getSession(Channel channel) {
        // 后面加个前置过滤器判断是否登录
        return channelMap.get(channel);
    }

    public static void setSession(Channel channel, Player player) {
        PlayerSession session = new PlayerSession(channel, player);
        channelMap.put(channel, session);
        uidMap.put(player.getId(), session);
    }

    public static PlayerSession delSession(Long uid) {
        PlayerSession session = uidMap.get(uid);
        if (session == null) return null;
        uidMap.remove(session.getPlayer().getId());
        channelMap.remove(session.getChannel());
        return session;
    }

    public static void delSession(Channel channel) {
        PlayerSession session = channelMap.get(channel);
        if (session == null) return;
        uidMap.remove(session.getPlayer().getId());
        channelMap.remove(session.getChannel());
    }

    public static Collection<PlayerSession> getSessions() {
        return channelMap.values();
    }

    public static <T> void notifyPlayer(Long uid, String route, T data) {
        PlayerSession session = uidMap.get(uid);
        if (session == null) { return; }
        MsgUtils.notifyClient(session.getChannel(), route, data, null, null);
    }

    public static Player getPlayer(Long uid) {
        PlayerSession session = getSession(uid);
        if (session == null) {
            return null;
        }
        return session.getPlayer();
    }

    /**
     * 广播消息
     * @param netMgrConsumer
     * @param uids 需要广播到的指定玩家，如果为空则广播所有玩家
     */
    public static <T> void broadcast(BiConsumer<_NetMgr, T> netMgrConsumer, T data, Long... uids) {
        if (uids == null || uids.length == 0) {
            // 广播所有玩家
            for (PlayerSession session : PlayerUtils.getSessions()) {
                Player player = session.getPlayer();
                if (player == null) { continue; }
                netMgrConsumer.accept(player._netMgr(), data);
            }
        } else {
            // 广播指定玩家
            for (Long uid : uids) {
                Player player = PlayerUtils.getPlayer(uid);
                if (player == null) { continue; }
                netMgrConsumer.accept(player._netMgr(), data);
            }
        }
    }
}
